#ifndef __LL_MAKE_DIRECTORY_HPP__
#define __LL_MAKE_DIRECTORY_HPP__

#include "llToken.hpp"
#include "llLex.hpp"
#include "llSyntax.hpp"
#include "llParseCommand.hpp"
using namespace llmake;

#include <list>
#include <string>
using namespace std;

#include <boost/tr1/memory.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace std::tr1;

namespace llmake
{
	typedef struct llMacroAndFunctionNode__
	{
		llTokenNode 		m_Name;
		llTokenList 		m_ARGV;
		llCommandList 		m_Body;
	} llMacroAndFunctionNode;
	typedef map<string,llMacroAndFunctionNode> llMacroAndFunctionMap;
	typedef map<string,llTokenList> llVariableMap;

	typedef struct llExecuteCommands__
	{
		string					m_Command;
		string					m_Body;
		list<string>			m_Src;
		list<string>			m_Dst;
	} llExecuteCommandNode;
	typedef list<llExecuteCommandNode> llExecuteCommands;
	
	typedef struct llTargetNode__
	{
		string 			m_Name;
		string			m_Path;
		list<string> 	m_Type;
		list<string>	m_LinkLibs;
	} llTargetNode;
	typedef map<string,llTargetNode> llTargetMap;
	
	class llMakeDirectory;
	typedef shared_ptr<llMakeDirectory> llMakeDirectoryPtr;
	class llMakeDirectory :public boost::enable_shared_from_this<llMakeDirectory>
	{
	public:
		llMakeDirectory(const string &folder);
		~llMakeDirectory();

		string getFolder(void)
		{
			return m_Folder;
		}
/*
		void insertSubDir(llMakeDirectoryPtr sub)
		{
			m_SubList.push_back(sub);
		}
*/
		void setTop(llMakeDirectoryPtr top)
		{
			m_Top= top;
		}

		void doParse(void);
		void doExecute(void);
		void insertVar(const string &name,const llTokenList &vars);
		void getVar(const string &name,llTokenList &vars);
		void insertMacroAndFunction(const string &name,const llMacroAndFunctionNode &macro_func);
		bool findMacroAndFunction(const string &name,llMacroAndFunctionNode &macro_func);
		void replaceCommandLists(llCommandList &commandsSrc,llCommandList &commandsDst,llVariableMap &varMap);
		void extractTokensVars(llTokenList & tokens);
		void jointTokens(llTokenList & tokens);
		string getFlags(const string & type);
		void insertFlags(const string & type,const string &flags);
		void insertExecuteCommand(const llExecuteCommandNode & comand);
		void insertTarget(const string &name,const llTargetNode &target);
		bool appendTargetLink(const string &name,list<string> &libs);
	private:
		string 									m_Folder;
		shared_ptr<llTokenEngine> 				m_TokenEngine;
		shared_ptr<llLexEngine> 				m_LexEngine;
		shared_ptr<llSyntaxEngine> 				m_SyntaxEngine;
		shared_ptr<llParseCommandEngine>		m_ParseCommandEngine;
		
		llMakeDirectoryPtr						m_Top;
//		list <llMakeDirectoryPtr> 				m_SubList;
// 
		llVariableMap							m_Vars;
		llMacroAndFunctionMap					m_MacroAndFunction;
		string									m_Cflags;
		string									m_Cxxflags;
		string									m_Ldflags;

		static llExecuteCommands				m_ExecCommand;
		static llTargetMap						m_Target;

		string									m_ReleaseCflags;
		string									m_ReleaseCxxflags;
		string									m_ReleaseLdflags;

		string									m_DebugCflags;
		string									m_DebugCxxflags;
		 string									m_DebugLdflags;
	};
};
#endif // __LL_MAKE_DIRECTORY_HPP__
